/**
 * Created by user on 2017/2/23.
 */
import ReplayPlayer from './ReplayPlayer'
import Type from './Type'
import { cloneObj, formatSocketMsg } from './Global'
const SHOW_DM_TYPE = [ Type.COMMON_TYPE.COMMON_DM_TEXT, Type.COMMON_TYPE.COMMON_DM_QUESTION ]
class PlayController {
  constructor() {
    this.start_time = null
    this.msgs = []
    this.formatMsg = []
    this.show_img_msg = []
    this.go_to_msg = []
    this.interval = null
    this.hasPLayedVideoTime = 0
    this.fullTime = 0
    this.clone_go_to_msg = []
    this.clone_dm_msg = []
    this.dm_msg = []
    this.allImages = []
  }
  setZero = (n) => {
    return n < 10 ? ('0' + n) : n
  }
  formatDiff = (diff) => {
    var d, h, m, s, ds = 24 * 60 * 60 * 1000, hs = 60 * 60 * 1000,
      ms = 60 * 1000, ss = 1000
    d = parseInt(diff / ds)
    diff = diff - d * ds
    h = parseInt(diff / hs)
    diff = diff - h * hs
    m = parseInt(diff / ms)
    diff = diff - m * ms
    s = parseInt(diff / ss)
    d = (d > 0) ? (d + '天 ') : ''
    h = this.setZero(h)
    m = this.setZero(m)
    s = this.setZero(s)
    return d + h + ':' + m + ':' + s
  }
  liveCallback = () => {}
  dmCallback = () => {}
  setDmCallback = (callback) => {
    this.dmCallback = callback
  }

  resetInitData() {
    for (var i in this.go_to_msg) {
      this.go_to_msg[i].done = false
    }
    for (var i in this.show_img_msg) {
      this.show_img_msg[i].done = false
    }
    for (var i in this.dm_msg) {
      this.dm_msg[i].done = false
    }
    this.hasPLayedVideoTime = 0
  }
  setInit(startTime, msgs, allData, liveCallback) {
    var formatMsg = []
    for (var i in msgs) {
      var t = formatSocketMsg(msgs[i])
      formatMsg.push(t)
    }
    this.allImages = allData.images
    this.formatMsg = formatMsg
    this.setCloneMsg()
    this.start_time = startTime
    this.liveCallback = liveCallback
    this.msgs = this.initMessages(this.formatMsg)
    this.show_img_msg = this.msgs.show_img_message
    this.go_to_msg = this.msgs.go_to_message
    this.dm_msg = this.msgs.dm_message
    this.fullTime = this.getFullTime(allData.audio.duration)
    this.hasPLayedVideoTime = 0
  }
  setCloneMsg(){
    var msgs = []
    for (let i in this.formatMsg){
      msgs.push(cloneObj(this.formatMsg[i]))
    }
    var video_time = 0
    var goto = [], gotoindex = 0, dm = [], dmindex = 0
    msgs.map((val, key) => {
      val.timestamp += video_time
      if (val.type === Type.COMMON_TYPE.COMMON_LIVE_SLIDE || val.type === Type.COMMON_TYPE.COMMON_START_VIDEO) {
        var index = val.data.index
        val.id = gotoindex
        gotoindex++
        goto.push(val)
        if (val.type === Type.COMMON_TYPE.COMMON_START_VIDEO) {
          video_time += (val.data.video_time * 1000)
        }
      }
      if (SHOW_DM_TYPE.includes(val.type)) {
        val.id = dmindex
        dmindex++
        dm.push(val)
      }
    })
    this.clone_go_to_msg = goto
    this.clone_dm_msg = dm
  }
  getFullTime(audio_time) {
    var t = audio_time
    for (var i in this.go_to_msg) {
      var c = this.go_to_msg[i]
      if (c.type === Type.COMMON_TYPE.COMMON_START_VIDEO) {
        t += c.data.video_time
      }
    }
    return t
  }
  setAllUnDone() {
    for (var i in this.go_to_msg) {
      this.go_to_msg[i].done = false
    }
    for (var i in this.show_img_msg) {
      this.show_img_msg[i].done = false
    }
  }
  initProgress(p, callback) {
    this.setAllUnDone()
    var diff = this.fullTime * 1000 * p
    if (this.show_img_msg.length > 0) {
      var obj = this.getMaxShowImage(diff)
      callback(obj)
    }
    if (this.go_to_msg.length > 0) {
      var obj = this.getMaxGoTo(diff)
      this.reSetPlayedVideoTime(obj)
      if (obj.playVideo) {
        obj.playVideoCallback = () => {
          this.hasPLayedVideoTime += obj.lastTask.data.video_time
        }
      }

      callback(obj)
    }
    var dmObj = this.getMaxDm(diff)
    this.dmCallback({
      task: dmObj
    })
  }
  getMaxDm(diff) {
    var task = null
    var len = this.dm_msg.length
    for (var i in this.clone_dm_msg) {
      var clone_current = this.clone_dm_msg[i]
      var current = this.dm_msg[i]
      if (clone_current.timestamp > diff + this.start_time) {
        current.done = false
        break
      } else {
        current.done = true
        task = current
      }
    }
    return task
  }
  getMaxGoTo(diff) {
    let maxUnDoneTask = null
    var len = this.go_to_msg.length
    for (let i in this.clone_go_to_msg) {
      var clone_current = this.clone_go_to_msg[i]
      var current = this.go_to_msg[i]
      if (clone_current.timestamp > diff + this.start_time) {
        current.done = false
        maxUnDoneTask = current
        break
      } else {
        current.done = true
      }
    }
    let obj = null
    if (!maxUnDoneTask) {
      let lastDoneTask = this.go_to_msg[len - 1]
      let lastCloneDoneTask = this.clone_go_to_msg[len - 1]
      if (lastDoneTask.type === Type.COMMON_TYPE.COMMON_LIVE_SLIDE) {
        let realAudioTime = diff - this.getBeforeIndexVideoTime(lastDoneTask.id)
        obj = {
          lastTask: lastDoneTask,
          playVideo: false,
          realAudioTime: realAudioTime,
          realVideoTime: 0,
          type: 'normal',
          hasPlayedVideoTime: this.getBeforeIndexVideoTime(lastDoneTask.id)
        }
      }
      if (lastDoneTask.type === Type.COMMON_TYPE.COMMON_START_VIDEO) {
        let video_diff_time = diff + this.start_time - lastCloneDoneTask.timestamp
        if (video_diff_time > (lastDoneTask.data.video_time * 1000)) {
          let realAudioTime = diff - this.getBeforeIndexVideoTime(lastDoneTask.id) - lastDoneTask.data.video_time * 1000
          obj = {
            lastTask: lastDoneTask,
            playVideo: false,
            realVideoTime: 0,
            realAudioTime: realAudioTime,
            type: 'normal',
            hasPlayedVideoTime: this.getBeforeIndexVideoTime(lastDoneTask.id) + lastDoneTask.data.video_time * 1000
          }
        }
        else {
          let realAudioTime = lastCloneDoneTask.timestamp - this.start_time - this.getBeforeIndexVideoTime(lastDoneTask.id)
          let realVideoTime = video_diff_time
          obj = {
            lastTask: lastDoneTask,
            playVideo: true,
            realVideoTime: realVideoTime,
            realAudioTime: realAudioTime,
            type: 'normal',
            hasPlayedVideoTime: this.getBeforeIndexVideoTime(lastDoneTask.id)
          }
        }
      }
    }
    else {
      if (maxUnDoneTask.id == 0) {
        obj = {
          lastTask: null,
          playVideo: false,
          realVideoTime: 0,
          realAudioTime: diff,
          type: 'first',
          hasPlayedVideoTime: 0
        }
      } else {
        let lastDoneTask = this.go_to_msg[maxUnDoneTask.id - 1]
        let lastCloneDoneTask = this.clone_go_to_msg[maxUnDoneTask.id - 1]
        if (lastDoneTask.type === Type.COMMON_TYPE.COMMON_LIVE_SLIDE) {
          let realAudioTime = diff - this.getBeforeIndexVideoTime(lastDoneTask.id)
          obj = {
            lastTask: lastDoneTask,
            playVideo: false,
            realVideoTime: 0,
            realAudioTime: realAudioTime,
            type: 'normal',
            hasPlayedVideoTime: this.getBeforeIndexVideoTime(lastDoneTask.id)
          }
        }
        if (lastDoneTask.type === Type.COMMON_TYPE.COMMON_START_VIDEO) {
          let video_diff_time = diff + this.start_time - lastCloneDoneTask.timestamp
          if (video_diff_time >= (lastDoneTask.data.video_time * 1000)) {
            let realAudioTime = diff - this.getBeforeIndexVideoTime(lastDoneTask.id) - (lastDoneTask.data.video_time * 1000)
            obj = {
              lastTask: lastDoneTask,
              playVideo: false,
              realVideoTime: 0,
              realAudioTime: realAudioTime,
              type: 'first',
              hasPlayedVideoTime: this.getBeforeIndexVideoTime(lastDoneTask.id) + (lastDoneTask.data.video_time * 1000)
            }
          } else {
            let realAudioTime = lastCloneDoneTask.timestamp - this.start_time - this.getBeforeIndexVideoTime(lastDoneTask.id)
            let realVideoTime = video_diff_time
            obj = {
              lastTask: lastDoneTask,
              playVideo: true,
              realVideoTime: realVideoTime,
              realAudioTime: realAudioTime,
              type: 'normal',
              hasPlayedVideoTime: this.getBeforeIndexVideoTime(lastDoneTask.id)
            }
          }
        }
      }
    }
    obj.realType = 'go_to'
    return obj
  }
  getMaxShowImage(diff) {
    var task = null
    var len = this.show_img_msg.length
    for (var i in this.show_img_msg) {
      var current = this.show_img_msg[i]
      if (current.timestamp > diff + this.start_time) {
        current.done = false
        task = current
        break
      } else {
        current.done = true
      }
    }
    var obj = {}
    if (!task) {
      obj = {
        lastTask: this.show_img_msg[len - 1],
        realAudioTime: diff,
        realVideoTime: 0,
        type: 'normal'
      }
    }
    else {
      if (task.id == 0) {
        obj = {
          lastTask: null,
          realAudioTime: diff,
          realVideoTime: 0,
          type: 'first'
        }
      } else {
        obj = {
          lastTask: this.show_img_msg[task.id - 1],
          realAudioTime: diff,
          realVideoTime: 0,
          type: 'normal'
        }
      }
    }
    obj.playVideo = false
    obj.realType = 'show_image'
    return obj
  }
  getBeforeIndexVideoTime(taskId) {
    var t= 0
    for (let i in this.go_to_msg) {
      let c = this.go_to_msg[i]
      if (c.id < taskId && c.type === Type.COMMON_TYPE.COMMON_START_VIDEO) {
        t += (c.data.video_time * 1000)
      }
    }
    return t
  }
  initMessages(messages) {
    var msgs = []
    for (let i in messages){
      msgs.push(cloneObj(messages[i]))
    }
    var show_flag = 0, goto_flag = 0, dm_flag = 0
    var show_img_message = []
    var go_to_message = []
    var dm_message = []
    msgs.map((val, key) => {
      var msg = val
      msg.done = false
      if (msg.type == Type.COMMON_TYPE.COMMON_LIVE_IMAGE) {
        msg.id = show_flag
        show_img_message.push(msg)
        show_flag++
      }
      if (msg.type == Type.COMMON_TYPE.COMMON_LIVE_SLIDE || msg.type == Type.COMMON_TYPE.COMMON_START_VIDEO) {
        msg.id = goto_flag
        go_to_message.push(msg)
        goto_flag++
      }
      if (SHOW_DM_TYPE.includes(msg.type)) {
        msg.id = dm_flag
        dm_message.push(msg)
        dm_flag++
      }
    })
    return {
      show_img_message: show_img_message,
      go_to_message: go_to_message,
      dm_message: dm_message
    }
  }
  stop() {
    this.interval && clearInterval(this.interval)
  }
  reSetPlayedVideoTime(obj) {
    let t = (obj.hasPlayedVideoTime / 1000)
    this.hasPLayedVideoTime = t
    return t
  }
  setPlayedVideoTime(time) {
    this.hasPLayedVideoTime += time
  }
  getPlayedVideoTime() {
    return this.hasPLayedVideoTime
  }
  getCurrentRealTime() {
    return ReplayPlayer.getCurrentTime() + this.hasPLayedVideoTime
  }
  setUpdateTimeCallback(fn) {
    this.updateTimeCallback = fn
  }
  updateTimeCallback = (time) => {}
  checkTask() {
    var current = parseInt(ReplayPlayer.getCurrentTime() * 1000)
    var diff = current + this.start_time
    if (this.show_img_msg.length > 0) {
      this.getMaxUnDoneShowTask(diff)
    }
    if (this.go_to_msg.length > 0) {
      this.getMaxUnDoneGoTask(diff)
    }
    if (this.dm_msg.length > 0) {
      this.getMaxUnDoneDmTask(diff)
    }
    if (current !== 0) {
      this.updateTimeCallback(current/1000 + this.hasPLayedVideoTime)
    }
  }
  getUpdateTime() {
    return ReplayPlayer.getCurrentTime() + this.hasPLayedVideoTime
  }
  getMaxUnDoneShowTask(diff) {
    for (var i = 0; i < this.show_img_msg.length; i++) {
      var current_task = this.show_img_msg[i]
      if (current_task.done) {
        continue
      }
      if (current_task.timestamp < diff) {
        this.doTask(current_task, () => {
          current_task.done = true
        })
      }
    }
  }
  getMaxUnDoneGoTask(diff) {
    var current = null
    for (var i = 0; i < this.go_to_msg.length; i++) {
      var current_task = this.go_to_msg[i]
      if (!current_task.done && current_task.timestamp < diff) {
        current = current_task
        break
      }
    }
    if (!current) {
      return
    }
    this.doTask(current, () => {
      if (current.type === Type.COMMON_TYPE.COMMON_START_VIDEO) {
        this.hasPLayedVideoTime += current.data.video_time
      }
      current.done = true
    })
  }
  getMaxUnDoneDmTask(diff) {
    for (var i = 0; i < this.dm_msg.length; i++) {
      var current_task = this.dm_msg[i]
      if (!current_task.done && current_task.timestamp < diff) {
        this.doTask(current_task, ()=> {
          current_task.done = true
        })
      }
    }
  }
  start() {
    this.interval && clearInterval(this.interval)
    this.checkTask()
    this.interval = setInterval(() => {
      this.checkTask()
    }, 1000)
  }
  doTask = (task, callback) => {
    if (SHOW_DM_TYPE.includes(task.type)) {
      this.dmCallback({
        type: task.type,
        task: task,
        callback: callback
      })
    } else {
      this.liveCallback({
        type: task.type,
        task: task,
        callback: callback
      })
    }

  }
}
module.exports = new PlayController()
